using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Collections.Generic;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using Liberty.Domain.CaseManagement;

using Liberty.Application.CaseManagement;
using Peradigm.Framework.Domain.Parties;


using Peradigm.Framework.UI.Web;

namespace Liberty.UI.Service.CaseManagement.Controls
{
    public partial class CaseEditView : AbstractLibertyControl, IView
    {
        CaseVariable caseVariable = new CaseVariable();

        #region Constants
        private const string
            MSG_SELECT_INJURY = "Select injury",
            MSG_SELECT_FACILITY = "Select medical facility",
            SELECT_VALUE = "0",
            OID = "Oid",
            NAME = "Name",
            DESCRIPTION = "Description",
            FORMAT_DATE = "{0:d}",
            TOGGLE_INJURY_SCRIPT = "ToggleInjuries( '{0}', '{1}', '{2}' );",
            TOGGLE_FAMILY_SECTION = "ToggleFamilySection( '{0}', '{1}', '{2}', '{3}' );",
            ON_CLICK_EVENT = "onclick",
            ON_CHANGE_EVENT = "onchange";
        #endregion

        #region Event Handlers
        private void Page_Init( object sender, EventArgs e )
        {
            this.BindDropDownControls();
        }

        protected void Page_Load( object sender, EventArgs e )
        {
        }

        protected void ddlInjury1_SelectedIndexChanged( object sender, EventArgs e )
        {
            if( ddlInjury1.SelectedIndex > 0 )
            { 
                ddlInjury2.Enabled = true;
            }
        }

        protected void ddlInjury2_SelectedIndexChanged( object sender, EventArgs e )
        {
            if( ddlInjury2.SelectedIndex > 0 )
            {
                ddlInjury3.Enabled = true;
            }
        }
        #endregion

        #region Methods
        public override void UpdateView()
        {
            Case aCase = this.Case;
            this.UpdateInjuriesViewWith( aCase );

            if ( this.Case.CurrentVisit == null )
            {
                aCase.AddVisit( new Visit() );
            }
            Visit currentVisit = aCase.CurrentVisit;
            if ( currentVisit.Facility != null )
            {
                this.ddlFacilities.SelectedValue = aCase.CurrentVisit.Facility.Oid.ToString();
            }
            this.txtDateInjured.Text = String.Format( FORMAT_DATE, aCase.DateOfInjury );
            this.txtDateMemberArrived.Text = String.Format( FORMAT_DATE, this.Visit.ArrivalDate );
            this.txtFamilyArrived.Text = String.Format( FORMAT_DATE, this.Visit.FamilyArrival );
            this.chkFamilyPresent.Checked = this.Visit.FamilyIsPresent;
            this.phFamilyPresentSection.Disabled = !this.chkFamilyPresent.Checked;
            this.txtCityOfOrigin.Enabled = this.chkFamilyPresent.Checked;
            this.txtFamilyArrived.Enabled = this.chkFamilyPresent.Checked;
            this.chkInvitationalTravel.Checked = this.Visit.HasInvitationalTravelOrders;
            if ( this.Visit.MethodOfTravel != null && this.Visit.MethodOfTravel != string.Empty )
            {
                foreach ( ListItem li in rdlMethodOfTravel.Items )
                {
                    if ( li.Text == this.Visit.MethodOfTravel )
                        li.Selected = true;
                }
            }

            this.txtCityOfOrigin.Text = this.Visit.OriginOfTravel;

            // Injury and member arrived dates cannot be in the future.
            this.rvDateInjured.MaximumValue = DateTime.Now.ToString( "MM/dd/yyyy" );
            this.rvDateMemberArrived.MaximumValue = DateTime.Now.ToString( "MM/dd/yyyy" );
            this.RegisterControlScripts();
        }

        public override void UpdateModel()
        {
            Case Case = this.Model as Case;
            if ( caseVariable.Case != null )
                this.Case = (Case)caseVariable.Case;

            if ( this.Visit != null )
            {
                //If the facility has changed, create a new Visit in the case to track the previous
                //information for visits.  Otherwise we'll update the old Visit with new information.
                if ( this.FacilityHasChanged() )
                {
                    this.Case.AddVisit( new Visit() );
                }
            }
            else
            {
                this.Case.AddVisit( new Visit() );
            }

            if ( this.txtDateInjured.Text.Length > 0 )
            {
                this.Case.DateOfInjury = Convert.ToDateTime( this.txtDateInjured.Text );
            }

            if ( ddlFacilities.SelectedIndex > 0 )
            {
                this.Visit.Facility = new Facility( ddlFacilities.SelectedItem.Value.ToString(), ddlFacilities.SelectedItem.Text );
                this.Visit.Facility.Oid = Convert.ToInt32( Visit.Facility.HspCode );
            }

            this.Visit.FamilyIsPresent = this.chkFamilyPresent.Checked;
            if ( this.Visit.FamilyIsPresent )
            {
                this.Visit.OriginOfTravel = this.txtCityOfOrigin.Text;
                this.Visit.HasInvitationalTravelOrders = this.chkInvitationalTravel.Checked;
                if ( rdlMethodOfTravel.SelectedItem != null )
                {
                    this.Visit.MethodOfTravel = this.rdlMethodOfTravel.SelectedItem.Text;
                }
                if( txtFamilyArrived.Text.Length > 0 )
                {
                    this.Visit.FamilyArrival = Convert.ToDateTime( this.txtFamilyArrived.Text );
                }
            }
            else
            {
                this.Visit.HasInvitationalTravelOrders = false;
                this.Visit.MethodOfTravel = String.Empty;
                this.Visit.OriginOfTravel = String.Empty;
                this.Visit.FamilyArrival = null;
            }
            
            if ( txtDateMemberArrived.Text.Length > 0 )
            {
                this.Visit.ArrivalDate = Convert.ToDateTime( this.txtDateMemberArrived.Text );
            }
           
            this.AddInjuries( this.ddlInjury1, 0 );
            this.AddInjuries( this.ddlInjury2, 1 );
            this.AddInjuries( this.ddlInjury3, 2 );

            this.Model = this.Case;
            caseVariable.Case = this.Case;
        }

        public void SaveModel()
        {
            this.UpdateModel();
            this.CaseController.SaveCase( this.Case );
        }
        #endregion

        #region Properties
        /// <summary>
        /// Delegate to register callbacks of the type InjurySelected.
        /// </summary>
        public event InjurySelectedEventHandler InjurySelectedListeners
        {
            add
            {
                i_InjurySelectedEvent += value;
            }
            remove
            {
                i_InjurySelectedEvent -= value;
            }
        }
        #endregion

        #region Private Methods
        private void UpdateInjuriesViewWith( Case aCase )
        {
            List<Injury> injuries = (List<Injury>)aCase.Injuries;
            if ( injuries.Count > 0 )
            {
                this.ddlInjury1.SelectedValue = injuries[0].TypeOfInjury.Oid.ToString();
                this.ddlInjury2.Enabled = true;
            }
            if ( injuries.Count > 1 )
            {
                this.ddlInjury2.SelectedValue = injuries[1].TypeOfInjury.Oid.ToString();
                this.ddlInjury2.Enabled = true;
                this.ddlInjury3.Enabled = true;
            }
            if ( injuries.Count > 2 )
            {
                this.ddlInjury3.SelectedValue = injuries[2].TypeOfInjury.Oid.ToString();
                this.ddlInjury3.Enabled = true;
            }
        }
        private void RegisterControlScripts()
        {
            string toggleInjuryScript = String.Format( TOGGLE_INJURY_SCRIPT, this.ddlInjury1.ClientID,
                this.ddlInjury2.ClientID, this.ddlInjury3.ClientID );
            this.ddlInjury1.Attributes[ON_CHANGE_EVENT] = toggleInjuryScript;
            this.ddlInjury2.Attributes[ON_CHANGE_EVENT] = toggleInjuryScript;
            this.txtDateInjured.Attributes.Add("onTextChanged", "formattedDate('" + this.txtDateInjured.ClientID + "');");
            string toggleFamilyScript = String.Format( TOGGLE_FAMILY_SECTION, this.chkFamilyPresent.ClientID, 
                this.phFamilyPresentSection.ClientID, this.txtCityOfOrigin.ClientID, this.txtFamilyArrived.ClientID);
            this.chkFamilyPresent.Attributes[ON_CLICK_EVENT] = toggleFamilyScript;
        }

        protected void ToggleFamilyPanel()
        {
            if( chkFamilyPresent.Checked )
            {
                rdlMethodOfTravel.Enabled = true;
                chkInvitationalTravel.Enabled = true;
                lblTravelMethod.Enabled = true;
                rdlMethodOfTravel.Enabled = true;

                foreach( ListItem li in rdlMethodOfTravel.Items )
                {
                    li.Enabled = true;
                }
            }
            else
            {
                chkInvitationalTravel.Enabled = false;
                rdlMethodOfTravel.Enabled = false;
                rdlMethodOfTravel.ClearSelection();
                lblTravelMethod.Enabled = true;
                rdlMethodOfTravel.Enabled = false;

                foreach( ListItem li in rdlMethodOfTravel.Items )
                {
                    li.Enabled = false;
                }
            }
        }

        private void BindDropDownControls()
        {
            List<TypeOfInjury> injuries = this.Injuries;
            this.BindInjuryList( this.ddlInjury1, injuries );
            this.BindInjuryList( this.ddlInjury2, injuries );
            this.BindInjuryList( this.ddlInjury3, injuries );
            this.BindFacilities();
        }

        private void AddInjuries( DropDownList ddlInjuries, int ctr )
        {
            List<Injury> injuries = (List<Injury>)this.Case.Injuries;

            if( ddlInjuries.SelectedIndex > 0 )
            {
                if( injuries.Count > ctr )
                {
                    if( injuries[ctr].TypeOfInjury.ToString() != ddlInjuries.SelectedItem.Text )
                    {
                        this.Case.RemoveInjury( injuries[ctr] );
                        this.Case.AddInjury( new Injury( this.CaseController.InjuryWith( (long)ddlInjuries.SelectedIndex ) ) );
                    }
                }
                else
                {
                    this.Case.AddInjury( new Injury( this.CaseController.InjuryWith( (long)ddlInjuries.SelectedIndex ) ) );
                }
            }
        }

        private bool FacilityHasChanged()
        {
            return ( this.Visit.Facility != null ) &&
                   ( this.Visit.Facility.Name != ddlFacilities.SelectedItem.Text );
        }

        private void BindFacilities()
        {
            ddlFacilities.Items.Clear();
            this.ddlFacilities.DataSource = CaseController.AllFacilities();
            this.ddlFacilities.DataTextField = NAME;
            this.ddlFacilities.DataValueField = OID;

            this.ddlFacilities.DataBind();
            this.ddlFacilities.Items.Insert( 0, new ListItem( MSG_SELECT_FACILITY, "0" ) );
        }

        private void BindInjuryList( DropDownList ddlInjury, IEnumerable items )
        {
            ddlInjury.Items.Clear();

            ddlInjury.DataSource = items;
            ddlInjury.DataValueField = OID;
            ddlInjury.DataTextField = DESCRIPTION;
            ddlInjury.DataBind();
            ddlInjury.Items.Insert( 0, new ListItem( MSG_SELECT_INJURY, "0" ) );
            ddlInjury.ClearSelection();
        }

        #endregion

        #region Private Properties
        private Case Case
        {
            get
            {
                return (Case)this.Model;
            }
            set
            {
                i_Case = value;
            }
        }

        private CaseController CaseController
        {
            get
            {
                return this.i_CaseController;
            }
        }

        private InjurySelectedEventHandler InjurySelectedEvent
        {
            get
            {
                return i_InjurySelectedEvent;
            }
        }

        private Visit Visit
        {
            get
            {
                return this.Case.CurrentVisit;
            }
        }

        private List<TypeOfInjury> Injuries
        {
            get
            {
                return CaseController.InjuryTypes();
            }
        }

        private bool IsInAsyncPostBack
        {
            get
            {
                return ScriptManager.GetCurrent( this.Page ).IsInAsyncPostBack;
            }
        }
        #endregion

        #region Construction and Finalization
        #endregion

        #region Data Elements
        private CaseController i_CaseController = new CaseController();
        private InjurySelectedEventHandler i_InjurySelectedEvent;
        private Case i_Case;
        #endregion


    }

}
